Segmentation and windowing

Assuming that your data are in the right format (see the Data chapter for more details), you can now run an analysis. We first demo here the usage of the interface and at the end show how to run an analysis without the UI. If you are interested in the methods you can see more in-depth explanation of what is occurring behind the scenes in a step by step demo.

Creating the interface

The interface is generated via the InteracSeg class contained in the morpho_segmentation module:

from morphodynamics.morpho_segmentation import InteractSeg
myUI = InteracSeg()
myUI.interface
from IPython.display import HTML
HTML(filename='images/UI_html.html')
Widgets export

The interface is composed of four parts:

  1. Data handling:

    • In the Choose main folder you should browse to the folder containing your data.

    • In the Saving folder you should select to which folder you want to export results.

    • The Load Segmentation button allows to re-load an existing analysis.

  2. Selecting channels in the Chose segmentation and signal channels (folders or tifs) section:

    • You should choose which channel you want to use for segmentation (left)

    • and from which channels you want to extract signal information (right). If you want to analyze the intensity of the segmentation channel, you have to select it as well as a signal.

    • Once selection is done you can load the data with the Initialize button.

  3. Computing type: select cluster, if you want computations to be submitted via a SLURMCluster job-queue.

  4. Set segmentation parameters:

    • Maxtime: select the last time point to be analyzed, by default the last available time point

    • Step: If for example you only want to analyze every second step, enter 2.

    • Bad frame: If you want to skip certain frames, enter them here, e.g. (e.g. 1,2,5-8,12)

    • Segmentation: Select your segmentation mode (see this chapter for more details)

    • Location X/Y: Location of the cell to track can be entered here manually.

    • Window depth/width: Desired dimensions (in px) of the windows.

    • Run the segmentation with the Click to segment button.

    • Save the results with the Save the segmentation button.

  5. Plot: The central plot shows an image and its current windowing. One can adjust:

    • The Time (frame) and the intensity range of the current image.

    • Whether to show windows or show labels of windows.

    • Which channel should be displayed.

    • Finally, you can click on the image to select which cell (if there are multiple ones) to track.

Note that when creating the interface myUI = InteractSeg you can pass additional arguments to avoid having to select them in the interface. This is particularly useful if you are running tests and have to repeatedly create the interface. For example you can use:

from morphodynamics.morpho_segmentation import InteractSeg
myUI = InteracSeg(expdir="path/to/my/data", seg_algo='ilastik')
myUI.interface

to specify where your data are and which algorithm to use. In that way you won’t have to browse to your data folder or change the algorithm.

Running a new analysis

In general follow these steps:

  1. Choose the data folder and the place where to save your results in the top two file browsers

  2. Choose which channels to use for segmentation and signal extraction in the Chose segmentation and signal channels (folders or tifs) part

  3. Now you can Initialize data, i.e. load the data set. Now you should see the first frame displayed in the figure.

  4. Select your computation resource and segmentation parameters.

  5. Select the cell to track (if necessary) by clicking on the image.

  6. Run the segmentation by clicking on Click to segment.

  7. Browse through the results.

  8. Save your data by clicking on Save segmentation.

Output

The results of the analysis are saved in the following way:

  • Segmentation images are saved in the segmented folder as segmented_k_0.tif, segmented_k_1.tif etc. Those images are labelled masks, i.e. each cell gets one label.

  • Tracking information is saved as binary images where only the selected cell appear. Images are called tracked_k_0.tif, tracked_k_1.tif etc.

  • The raasterized cell contours where pixel values correspond to curvilinear distance are stored as 32-bits images rasterized_k_0.tif, rasterized_k_1.tif etc.

  • The binary window images with window boundaries are stored as window_image_k_0.tif, window_image_k_1.tif etc.

  • The list of pixel indexes indicating to which window each pixel belongs are stored as pickle files window_k_0.pkl, window_k_1.pkl etc.

  • Other information such as spline functions are stored in a pickled Results.pkl file.

  • Parameters of the experiments are saved in a human readable Parameters.yml file.

Loading an existing analysis

In general follow these steps:

  1. Choose the folder that contains your results (Results.pkl and Parameters.yml files).

  2. Cick on Load segmentation

You should now see a UI updated with all parameters set when analyzing the dataset.

Running an analysis without UI

In some cases it is preferable to use the code without the interface. This is in particular true if you want to run a batch of analysis. We present here an example of how to do that.

Just like before, we use the InteractSeg class defined in the morpho_segmentation module as an object that simplifies the handling of all the parts of the code. We need to provide the data location as well as a folder to save the data:

expdir = '../synthetic/data'
result_dir = '../synthetic/data/Results_step'

and specify which channels we intend to use. We need to provide the name of the stack used for segmentation:

morpho_name = 'synth_ch1.h5'

as well as a list of stack names whose intensity we want to analyze:

signal_name = ['synth_ch2.h5','synth_ch3.h5']

Now we can create our segmentation object:

from morphodynamics.morpho_segmentation import InteractSeg
myUI = InteractSeg(expdir=expdir, morpho_name=morpho_name, signal_name=signal_name,
             resultdir=result_dir, createUI=False)

It is important to know that the myUI instance of InteracSeg contains itself the main objects used for the analysis, Parameters, Results and Data as parameters, so there is no need to create them separately.

We can now load the data by initializing the experiment:

myUI.initialize()

Now we can adjust the parameters for the segmentation (seg_algo) and windowing (widht and depth)

myUI.param.width = 5
myUI.param.depth = 5
myUI.param.lambda_ = 10
myUI.param.seg_algo = 'ilastik'

Finally we can run the analysis:

myUI.run_segmentation()
frames splining:   0%|          | 0/40 [00:00<?, ?it/s]
frames splining:   2%|▎         | 1/40 [00:04<03:10,  4.89s/it]
frames splining:  62%|██████▎   | 25/40 [00:04<00:51,  3.43s/it]
frames splining: 100%|██████████| 40/40 [00:05<00:00,  7.91it/s]
frames rasterize:   0%|          | 0/39 [00:00<?, ?it/s]
frames rasterize:   3%|▎         | 1/39 [00:03<02:22,  3.75s/it]
frames rasterize:  38%|███▊      | 15/39 [00:03<01:03,  2.63s/it]
frames rasterize: 100%|██████████| 39/39 [00:03<00:00,  9.88it/s]
frames compute windows:   0%|          | 0/40 [00:00<?, ?it/s]
frames compute windows:   0%|          | 0/40 [00:00<?, ?it/s]

---------------------------------------------------------------------------
FileNotFoundError                         Traceback (most recent call last)
<ipython-input-8-c5dcfd9178be> in <module>
----> 1 myUI.run_segmentation()

/usr/share/miniconda/lib/python3.7/site-packages/morphodynamics/morpho_segmentation.py in run_segmentation(self, b)
    383             self.param,
    384             self.client,
--> 385             skip_segtrack=self.skip_trackseg,
    386         )
    387         self.show_segmentation(change="init")

/usr/share/miniconda/lib/python3.7/site-packages/morphodynamics/analysis_par.py in analyze_morphodynamics(data, param, client, only_seg, keep_seg, skip_segtrack)
     97 
     98     # create windows
---> 99     windowing_all(s_all, res.orig, param, J, I, client)
    100 
    101     # define windows for each frame and compute pairs of corresponding

/usr/share/miniconda/lib/python3.7/site-packages/morphodynamics/analysis_par.py in windowing_all(s_all, ori_all, param, J, I, client)
    357     ]
    358     for k in tqdm(range(len(s_all)), "frames compute windows"):
--> 359         compute_windows[k].result()
    360         compute_windows[k].cancel()
    361 

/usr/share/miniconda/lib/python3.7/site-packages/distributed/client.py in result(self, timeout)
    223         if self.status == "error":
    224             typ, exc, tb = result
--> 225             raise exc.with_traceback(tb)
    226         elif self.status == "cancelled":
    227             raise result

/usr/share/miniconda/lib/python3.7/site-packages/morphodynamics/analysis_par.py in windowing()
    322     name2 = os.path.join(save_path, "window_image_k_" + str(k_iter) + ".tif")
    323 
--> 324     c = utils.load_rasterized(save_path, k_iter)
    325     w, _, _ = create_windows(c, splevper(ori, s), J, I)
    326 

/usr/share/miniconda/lib/python3.7/site-packages/morphodynamics/utils.py in load_rasterized()
    127 
    128     image = skimage.io.imread(
--> 129             os.path.join(location, "rasterized_k_" + str(frame) + ".tif")
    130         )
    131 

/usr/share/miniconda/lib/python3.7/site-packages/skimage/io/_io.py in imread()
     46 
     47     with file_or_url_context(fname) as fname:
---> 48         img = call_plugin('imread', fname, plugin=plugin, **plugin_args)
     49 
     50     if not hasattr(img, 'ndim'):

/usr/share/miniconda/lib/python3.7/site-packages/skimage/io/manage_plugins.py in call_plugin()
    207                                (plugin, kind))
    208 
--> 209     return func(*args, **kwargs)
    210 
    211 

/usr/share/miniconda/lib/python3.7/site-packages/skimage/io/_plugins/tifffile_plugin.py in imread()
     34 
     35     # read and return tiff as numpy array
---> 36     with TiffFile(fname, **kwargs_tiff) as tif:
     37         return tif.asarray(**kwargs)

/usr/share/miniconda/lib/python3.7/site-packages/tifffile/tifffile.py in __init__()
   2792                     raise TypeError(f'unexpected keyword argument: {key}')
   2793 
-> 2794         fh = FileHandle(arg, mode=mode, name=name, offset=offset, size=size)
   2795         self._fh = fh
   2796         self._multifile = bool(_multifile)

/usr/share/miniconda/lib/python3.7/site-packages/tifffile/tifffile.py in __init__()
   8295         self.is_file = None
   8296         self._lock = NullContext()
-> 8297         self.open()
   8298 
   8299     def open(self):

/usr/share/miniconda/lib/python3.7/site-packages/tifffile/tifffile.py in open()
   8308             self._file = os.path.realpath(self._file)
   8309             self._dir, self._name = os.path.split(self._file)
-> 8310             self._fh = open(self._file, self._mode)
   8311             self._close = True
   8312             if self._offset is None:

FileNotFoundError: [Errno 2] No such file or directory: '/home/runner/work/MorphoDynamics/MorphoDynamics/synthetic/data/Results_step/segmented/rasterized_k_0.tif'

And save the output:

myUI.export_data()